package k8s

import (
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/api/core/v1"
	"k8s.io/client-go/kubernetes/scheme"
	"fmt"
	"io/ioutil"
)

type K8sPod struct {
	Name string							`json:"name"`
	Namespace string					`json:"namespace"`
	Labels map[string]string			`json:"labels"`
	Status string						`json:"status"`
	NodeIp string						`json:"nodeip"`
	NodeName string						`json:"nodename"`
	PodIp string						`json:"podip"`
	RestartCount int32					`json:"restartcount"`
	CreateDate string					`json:"createdate"`

	NodeSelector map[string]string		`json:"nodeselector"`
	ServerAccount string				`json:"serveraccount"`

	CurrentConditions []v1.PodCondition `json:"currentconditions"`

	Containers []v1.Container 			`json:"containers"`
	Volumes []v1.Volume					`json:"volumes"`

}

func GetKubernetesPodDetail(ns string,podName string)(k8sPod K8sPod,evns []Event,err error) {

	pod,_ := clientset.CoreV1().Pods(ns).Get(podName,metav1.GetOptions{})

	//fmt.Printf("%+v\n",pod.Status.Conditions)

	k8sPod = K8sPod{
		Name: pod.Name,
		Namespace: pod.Namespace,
		Labels: pod.Labels,
		CreateDate: pod.CreationTimestamp.Format("2006-01-02 15:03:04"),
		Status: string(pod.Status.Phase),

		NodeName: pod.Spec.NodeName,
		PodIp: pod.Status.PodIP,

		RestartCount: pod.Status.ContainerStatuses[0].RestartCount,

		NodeSelector: pod.Spec.NodeSelector,
		ServerAccount: pod.Spec.ServiceAccountName,

		CurrentConditions: pod.Status.Conditions,

		Containers: pod.Spec.Containers,
		Volumes: func()(vol []v1.Volume)	 {
			for _,volumen :=  range pod.Spec.Volumes {
				if volumen.NFS != nil {
					vol = append(vol,volumen)
				}
			}
			return
		}(),

	}


	events, _ := clientset.CoreV1().Events(ns).Search(scheme.Scheme, pod)
	for _,item := range events.Items {

		evns = append(evns,Event{
			//Name: item.Name,
			//Kind: item.InvolvedObject.Kind,
			//
			//
			//Type: item.Type,

			Message: item.Message,
			Source: item.Source.Component + " " + item.Source.Host,
			ChildObject: item.InvolvedObject.FieldPath,
			Reason: item.Reason,
			Num: item.Count,
			LastOccurTime: item.LastTimestamp.Format("2006-01-02 15:04:05"),
		})
	}

	fmt.Println("get log from pods")

	tailNum := int64(100)
	logoption := v1.PodLogOptions{
		Container: pod.Spec.Containers[0].Name,
		Follow: false,
		Previous: false,
		Timestamps: true,
		TailLines: &tailNum,
	}



	podLogReader,err := clientset.CoreV1().RESTClient().Get().Namespace(ns).Name(podName).Resource("pods").SubResource("log").VersionedParams(&logoption,scheme.ParameterCodec).Stream()

	if err != nil {
		fmt.Println("get pod's log error is" ,err.Error())
		return
	}
	defer podLogReader.Close()
	result, err := ioutil.ReadAll(podLogReader)
	if err != nil {
		fmt.Println("this error is",err.Error())
	}
	//fmt.Println(string(result))

	loglines := ParseToLogLines(string(result))

	for _,line := range loglines {
		fmt.Printf("%+v\n",line)
	}
	return

}

func DeleteKubernetesPod(ns string,podName string)(err error)  {

	err = clientset.CoreV1().Pods(ns).Delete(podName,&metav1.DeleteOptions{})
	if err != nil {
		fmt.Println("fail to delete pod :" , err.Error())
	}
	return
}

func GetKubernetesPodMetadata(ns string,podName string)(pod *v1.Pod,err error)  {

	pod,_ = clientset.CoreV1().Pods(ns).Get(podName,metav1.GetOptions{})
	pod.Kind = "Pod"
	pod.APIVersion = "v1"
	if err != nil {
		fmt.Println("fail to delete pod :" , err.Error())
	}
	return
}

func UpdateKubernetesPodMetadata(ns string,podName string,payload []byte)( error)  {
	req := clientset.CoreV1().
		RESTClient().
		Put().
		Namespace(ns).
		Name(podName).
		Resource("pods").
		SetHeader("Content-Type", "application/json").
		Body(payload)


	err := req.Do().Error()
	if err != nil {
		fmt.Println("put pod error is: " , err.Error())
		return err
	}
	return nil
}